/*
Copyright 2007 Raymond Giorgi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */

package edu.pitt.CS2510.NodeActions;

import java.util.ArrayList;

import edu.pitt.CS2510.Coordinate;
import edu.pitt.CS2510.Update;
import edu.pitt.CS2510.Messages.SupplyMessage;
import edu.pitt.CS2510.Nodes.CentralNode;

/**
 * 
 * @author NoOne
 * 
 *         This class defines all the possible actions a central node can take.
 *         A central node instantiates this class in its constructor.
 */
public class CentralNodeActions implements NodeActionsInterface {
	private CentralNode parent = null;

	/**
	 * Gives the class access to its parent (instance of Node)
	 * 
	 * @param parent
	 */
	public CentralNodeActions(CentralNode parent) {
		this.parent = parent;
	}

	/**
	 * If the system is performing correctly, this method should not be called.
	 * Useful in debugging
	 */
	@Override
	public void processAttackMessage(Coordinate co) {
		System.err
				.println("AttackMessage should not be sent to a Central Node");
	}

	/**
	 * This method gets called when a Supervisor node has finished its task. It
	 * inserts both the Supervisor and all its grunts back into the 'idleNode'
	 * list
	 */
	@Override
	public void processDoneMessage(int from, ArrayList<Integer> nodes) {
		final ArrayList<Integer> coordinators = new ArrayList<Integer>(parent
				.getCoordinators());
		parent.getCoordinators().clear();
		for (final Integer node : coordinators) {
			if (node != from) {
				parent.getCoordinators().add(node);
			} else {
				for (final Integer id : nodes) {
					parent.addIdleNode(id);
				}
			}
		}
	}

	/**
	 * If the system is performing correctly, this method should not be called.
	 * Useful in debugging
	 */
	@Override
	public void processQuitMessage() {
		System.out.println("QuitMessage should not be sent to a Central Node");
	}

	/**
	 * This method gets called when a Supervisor is requesting backup. It pulls
	 * nodes off of
	 */
	public void processRequestMessage(int from, int no) {
		final ArrayList<Integer> nodes = new ArrayList<Integer>();
		for (int i = 0; i < no; i++) {
			if (!parent.getIdleNodes().isEmpty()) {
				nodes.add(parent.removeIdleNode(0));
			} else {
				parent.addRequest(from, no);
			}
		}
		parent.sendMessage(new SupplyMessage(from, parent.getId(), nodes));
	}

	/**
	 * If the system is performing correctly, this method should not be called.
	 * Useful in debugging
	 */
	@Override
	public void processSupplyMessage(ArrayList<Integer> list) {
		System.err
				.println("SupplyMessage should not be sent to a Central Node");
	}

	/**
	 * This method is called a Supervisor has changed some feature of the map
	 */
	@Override
	public void processUpdateMessage(ArrayList<Coordinate> updates, int from) {
		updateGrid(updates);
		parent.initializeUpdateList();
		for (final Coordinate co : updates) {
			parent.addGridChange(new Update(from, co));
		}
	}

	/**
	 * 
	 */
	@Override
	public void updateGrid(ArrayList<Coordinate> coordinates) {
		// TODO Auto-generated method stub

	}
}
